#!/usr/bin/env python
import sys
from os.path import isfile

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import numpy as N

from ui_Plot_Widget import Ui_Plot_Widget
from Plot_Options import Plot_Options_Dialog

from Snide_List import Famous_Quotes

from plotDataClass import LinePlotClass

file_filters = ['Python Files (*.py *.pyc)',
                'Text (*.txt)',
                'HDF5 (*.hdf *.h5)',
                'SubPlot Files (*.spf)', 
                'All Files (*.*)']


class Plot_Widget(QWidget):
    '''data2plot LinePlotClass instance.  It does not require an x array to
    plot and multiple y arrays may be held in a single instance.  
    '''
    def __init__(self, data2plot=None, parent = None):
        QWidget.__init__(self, parent)
        self.ui = Ui_Plot_Widget()
        self.ui.setupUi(self)
        
        self.plotTitle = "Subplot"
        self.xtitle = "x-axis"
        self.ytitle = "y-axis"
        self.grids = False #this is used because I can't find the pylab bool status for the grids
        self.logx = False
        self.logy = False
        #self.xscaling = None
        #self.yscaling = None
        self.xscale = None
        self.yscale = None
        self.plotlist = {}#will contain all of the y values in the plot
        self.xlist = {}#used just for reference
        #self.lpclist = []
        if data2plot:
            self.initialize_plot(data2plot)
        
        self.connect(self.ui.btn_TestPlot, SIGNAL("clicked()"),
                     self.test_plot)
        self.connect(self.ui.btn_AutoScale, SIGNAL("clicked()"),
                     self.autoscale_plot)
        self.connect(self.ui.btn_Clear, SIGNAL("clicked()"),
                     self.clear_plot)
        self.connect(self.ui.btn_PlotOptions, SIGNAL("clicked()"),
                     self.plot_option_dialog)

    
    def plot_option_dialog(self):
        mpl = self.ui.mpl_widget.canvas
        self.od = Plot_Options_Dialog(self.plotlist, self)
        self.od.plottitle_lineEdit.setText(mpl.PlotTitle)
        self.od.xlabel_lineEdit.setText(mpl.xtitle)
        self.od.ylabel_lineEdit.setText(mpl.ytitle)
        self.od.xmin_lineEdit.setText(str(mpl.ax.get_xlim()[0]))
        self.od.xmax_lineEdit.setText(str(mpl.ax.get_xlim()[1]))
        self.od.ymin_lineEdit.setText(str(mpl.ax.get_ylim()[0]))
        self.od.ymax_lineEdit.setText(str(mpl.ax.get_ylim()[1]))
        self.od.gridlines_cb.setChecked(self.grids)
        self.od.logx_cb.setChecked(self.logx)
        self.od.logy_cb.setChecked(self.logy)
        
                
        if self.od.exec_():
            self.xscale = (float(self.od.xmin_lineEdit.text()),float(self.od.xmax_lineEdit.text()))
            self.yscale = (float(self.od.ymin_lineEdit.text()),float(self.od.ymax_lineEdit.text()))
            self.logx = self.od.logx_cb.isChecked()
            self.logy = self.od.logy_cb.isChecked()
            self.grids = self.od.gridlines_cb.isChecked()
            self.plotTitle = self.od.plottitle_lineEdit.text()
            self.xtitle = self.od.xlabel_lineEdit.text()
            self.ytitle = self.od.ylabel_lineEdit.text()
            #mpl.ax.grid(self.grids)
            #mpl.format_labels()
            #mpl.draw()
        
            self.updatePlot()
    ####################
    ###################
    '''you are here. perhaps you need to add the logx logy to the dict and
    let the program do the rest'''
    ####################
    ####################
    #####################
    def updatePlot(self):
        mpl = self.ui.mpl_widget.canvas
        for value in self.plotlist.values():
            value[0].set_markersize(value[1].markerSize)
            value[0].set_marker(value[1].markerStyle)
            value[0].set_linewidth(value[1].lineWidth)
            value[0].set_linestyle(value[1].lineStyle)
            if value[1].lineColor is not None:
                value[0].set_color(value[1].lineColor)
        
        mpl.ax.set_xlim(self.xscale)
        mpl.ax.set_ylim(self.yscale)
        mpl.ax.set_xscale(self.axis_scaling(self.logx))
        mpl.ax.set_yscale(self.axis_scaling(self.logy))
        mpl.ax.grid(self.grids)
        mpl.format_labels()
        mpl.draw()
        
    def axis_scaling(self, bool):
        if bool is True:
            return 'log'
        else:
            return 'linear'
    
    def program_close(self):
        sys.exit()

    def clear_plot(self):
        self.ui.mpl_widget.canvas.ax.cla()
        self.ui.mpl_widget.canvas.format_labels()
        self.ui.mpl_widget.canvas.draw()
        self.plotlist = {}
    
    def initialize_plot(self, data2plot):
        
        if data2plot.xy is False and type(data2plot.__ydata__()) is dict:
            #print "No X array and Multiple Y's"
            ydata_dict = data2plot.__ydata__()
            for yLPC in ydata_dict.itervalues():
                self.plotlist[yLPC.label]=((self.ui.mpl_widget.canvas.ax.plot(yLPC.__ydata__(),\
                                            label = yLPC.label,))[0],\
                                            yLPC)
        elif data2plot.xy is False:
            #print "No X array and Single Y"
            self.plotlist[data2plot.label]=((self.ui.mpl_widget.canvas.ax.plot(data2plot.__ydata__(),\
                                            label = data2plot.label))[0],\
                                            data2plot)
        
        elif data2plot.xy is True and type(data2plot.__ydata__()) is dict:
            #print "Single X, Multiple Y's"
            self.xlist[data2plot.xlabel] = data2plot.__xdata__()
            ydata_dict = data2plot.__ydata__()
            for yLPC in ydata_dict.itervalues():#yLPC= y-LinePlotClass
                self.plotlist[yLPC.label]=(self.ui.mpl_widget.canvas.ax.plot(data2plot.__xdata__(), yLPC.__ydata__(),\
                                            label = yLPC.label)[0],\
                                            yLPC)
                                                
        elif data2plot.xy is True and type(data2plot.__ydata__()) is not list:
            self.plotlist[data2plot.label]=((self.ui.mpl_widget.canvas.ax.plot(data2plot.__xdata__(),data2plot.__ydata__(),\
                                            label = data2plot.label))[0],\
                                            data2plot)
        

        #for line in self.plotlist.values():
            #print type(line)
            #line[0].set_marker('o')
        #print self.plotlist.keys()
        self.ui.mpl_widget.canvas.draw()
        #self.ui.mpl_widget.canvas.ax.set_xlim(2,None)

        
            
    def dict_value(self, dictionary):
        return dictionary.values()[0]
    
    def dict_key(self, dictionary):
        return dictionary.keys()[0]
              
    def autoscale_plot(self):
        self.ui.mpl_widget.canvas.ax.autoscale_view(tight = False, scalex=True, scaley=True)
        self.ui.mpl_widget.canvas.draw()
        #for entry in self.lpclist:
            #print entry.label
    
    def test_plot(self):
        self.generate_dummy_data()
    
    def generate_dummy_data(self):
        x = N.arange(0,10, N.random.random())
        y = N.cos(x-N.random.random())
        xdict = {'x':x}
        ydict = {'test':y}
        self.add_trace([xdict, ydict])

    def add_trace(self, dataDict):
        data2plot = LinePlotClass(dataDict)
        self.initialize_plot(data2plot)
    
    def createDictFromList(self, LIST):
        
        #keys = DICT.keys()
        #print len(DICT)
        dictstring = "dict("
        if len(LIST) > 1:
            for i in xrange(len(LIST)-1):
                dictstring += "'%s'=%s," % (LIST[i],LIST[i])
            dictstring += "'%s'=%s)" % (LIST[i+1],LIST[i+1])
            return dictstring
        else:
            dictstring += "'%s'=%s)" % (LIST[0],LIST[0])
            print dictstring
            return dictstring
    
    def getPlotScript(self):
        activeYLPC = []
        for value in self.plotlist.values():
            activeYLPC.append(value[1].label)
            #activeLPC[value[1].label]=value[1]
        
        activeXLPC = []
        activeXLPC.append(value[1].xlabel)
        activeLPC = [self.createDictFromList(activeXLPC),self.createDictFromList(activeYLPC)]
           
        mpl = self.ui.mpl_widget.canvas    
        plotDict = dict(plotTitle = mpl.PlotTitle,\
                xTitle = mpl.xtitle,\
                yTitle = mpl.ytitle,\
                logx = self.logx,\
                logy = self.logy,\
                grids = self.grids,\
                xscale = mpl.ax.get_xlim(),\
                yscale = mpl.ax.get_ylim(),\
                lpc_dict = activeLPC)
                
        return plotDict
    
    def plotFromScript(self, plotDict):
        mpl = self.ui.mpl_widget.canvas
        self.plotTitle = plotDict.get('plotTitle')
        self.xtitle = plotDict.get('xTitle') 
        self.ytitle = plotDict.get('yTitle')
        #mpl.ax.set_xscale(plotDict.get('xscaling'))
        #mpl.ax.set_yscale(plotDict.get('yscaling'))
        self.logx = plotDict.get('logx')
        self.logy = plotDict.get('logy')
        self.xscale = plotDict.get('xscale')
        self.yscale = plotDict.get('yscale')
        self.grids = plotDict.get('grids')
##        mpl.ax.set_xlim(plotDict.get('xscale'))
##        mpl.ax.set_ylim(plotDict.get('yscale'))
##        mpl.ax.grid(plotDict.get('grids'))
        
        #mpl.format_labels()
        
        self.initialize_plot(plotDict.get('lpc_dict'))
        self.updatePlot()
        
        


if __name__ == "__main__":
    def printDictString(DICT):
        
        keys = DICT.keys()
        #print len(DICT)
        dictstring = "dict(\r"
        for i in xrange(len(keys)-1):
            dictstring += "'%s'=%s,\r" % (keys[i],keys[i])
        dictstring += "'%s'=%s)" % (keys[i+1],keys[i+1])
        return dictstring

    def printDICTLIST(DICTLIST):
        if type(DICTLIST) is list and type(DICTLIST[0]) is dict:
            print 'LPC'
            #lpcstring = "[%s,%s]"%(printDictString(DICTLIST[0]),printDictString(DICTLIST[1]))
            #print lpcstring
            #return lpcstring
        else:
            print "Incorrect Input Provided"
            
##    def printDict2(DICT):
##        print ','.join([`key` for key in DICT.iterkeys()])    
    
    def printDict3(DICT):
        if DICT.has_key('lpc_dict'):
            temp_dict = DICT.pop('lpc_dict')
            print type(temp_dict)
            
            scriptlist = []
            for item in DICT.iteritems():
                scriptlist.append(item)
            
            scriptlist.append(('lpc_dict',printDICTLIST(temp_dict)))
            
            print scriptlist
            
        else:
            print "Incorrect Dictionary Provided, no 'lpc_dict'"
        
        
    app = QApplication(sys.argv)
    x = N.arange(0,20, N.random.random())
    y = N.cos(x-N.random.random())
    y2 = N.sin(x-N.random.random())
    y3 = 2*N.sin(x-N.random.random())
    dummyDict = {'None':None}
    xdict = {'x':x*2}
    #xdict = {'None':None}
    ydict = {'y':y, 'y2':y2, 'y3':y3}
    #ydict = {'y':y}
    #data2plot = LinePlotClass([dummyDict,ydict])
    data2plot = LinePlotClass([xdict,ydict])
    #printDictString(ydict)
    #printDict2(ydict)
    plot = Plot_Widget(data2plot)
    temp_dict = plot.getPlotScript()
    
    #print str(temp_dict)
    #print ""
    dalist = []
    for item in temp_dict.iteritems():
        #print str(item)
        dalist.append(item)
    real_dict = dict(dalist)
    print real_dict
    plot.show()
    

    print ""
    #print data2plot.xy
    plotDict = dict(plotTitle = "Go Joe",\
                xTitle = "X AXIS",\
                yTitle = "Y AXIS",\
                logx = False,\
                logy = False,\
                xscale = (0,20),\
                yscale = (-5,5),\
                grids = True,\
                lpc_dict = data2plot)
    #dalist = []
    #for item in plotDict.iteritems():
    #    dalist.append(item)
    #print dalist
    #print ""
    #printDict3(plotDict)
    #print plotDict
    #printDictString(plotDict)  
##    plot = Plot_Widget()
##    plot.plotFromScript(plotDict)
##    plot.show()
##    for entry in plot.plotlist:
##        print entry.label

    #print plot.plotlist
    sys.exit(app.exec_())

